package com.xxx.springboot.aop;

import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import com.xxx.springboot.constant.Constants;
import com.xxx.springboot.pojo.UserInfo;

/**
 * 慢日志AOP
 */
@Component
@Aspect
@Log4j2
public class LogAspect {

	static int TIME_OUT = 100; // 超时时间，单位：ms

    @Pointcut("execution(public * com.xxx.springboot.controller.*.*(..))")
    public void logPointcut() {
    	
    }

    @Around("logPointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = null;
        Throwable exception = null;
        try {
            result = joinPoint.proceed();
        } catch (Throwable throwable) {
            exception = throwable;
        }
        long cost = System.currentTimeMillis() - start;
        String className = joinPoint.getSignature().getDeclaringTypeName();
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        String userName = "unknown";
        Object object = RequestContextHolder.currentRequestAttributes().
                getAttribute(Constants.USER_INFO_SESSION_KEY, RequestAttributes.SCOPE_SESSION);
        if (null != object) {
            userName = ((UserInfo) object).getUserName();
        }
        if (cost < TIME_OUT) { // 超时阀值
            log.info("{}|{}|{}|{}|{}ms", userName, className, methodName, args, cost);
        } else {
            log.warn("slow|{}|{}|{}|{}|{}ms", userName, className, methodName, args, cost);
        }
        if (null != exception) {
            throw exception;
        }
        return result;
    }
}
